package automately.core.services.api.routers; import automately.core.data.Job; import automately.core.data.User; import automately.core.data.UserData; import com.hazelcast.core.IMap; import io.jsync.Handler; import io.jsync.app.ClusterApp; import io.jsync.app.core.Cluster; import io.jsync.app.core.Config; import io.jsync.http.HttpServerRequest; import io.jsync.json.JsonObject; import io.jsync.json.impl.Base64; import io.netty.handler.codec.http.HttpHeaders; public abstract class ApiHandler implements Handler<HttpServerRequest> { private Cluster cluster; private Config config; private boolean secure = true; public ApiHandler() { this(true); } public ApiHandler(boolean secure) { this.cluster = cluster(); this.config = cluster.config(); this.secure = secure; } protected Cluster cluster() { if (cluster == null) { cluster = ClusterApp.activeInstance().cluster(); } return cluster; } protected IMap<String, User> users() { return cluster().data().persistentMap("users"); } protected IMap<String, Job> jobs() { return cluster().data().persistentMap("jobs"); } /** * This returns the child JsonObject for the config * automately.core * * @return JsonObject */ protected JsonObject coreConfig() { Cluster cluster = cluster(); JsonObject rawConfig = cluster.config().rawConfig(); if (!rawConfig.containsField("automately")) { rawConfig.putValue("automately", new JsonObject().putValue("core", new JsonObject())); } return rawConfig.getObject("automately").getObject("core"); } protected void defaultResponse(HttpServerRequest req) { JsonObject response = new JsonObject(); response.putString("message", "Bad Request"); response.putString("description", "This is not a valid API request."); req.response().setStatusCode(400); req.response().setContentType("application/json"); req.response().end(response.encode(false)); } protected void errorResponse(HttpServerRequest req, String message, String description, Integer statusCode) { JsonObject response = new JsonObject(); response.putString("message", message); response.putString("description", description); req.response().setStatusCode(statusCode); req.response().setContentType("application/json"); req.response().end(response.encode(false)); } @Override public void handle(HttpServerRequest req) { req.response().setContentType("application/json"); // Set the content type firstx /** * Begin Authorization */ User mUser = null; boolean authenticated = false; if (req.headers().contains(HttpHeaders.Names.AUTHORIZATION)) { String authString = req.headers().get(HttpHeaders.Names.AUTHORIZATION); if (authString.split(" ").length > 1) { authString = authString.split(" ")[1]; String decodedAuth = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.decode(authString)); if (decodedAuth != null) { if (decodedAuth.split(":").length > 1) { String username = decodedAuth.split(":")[0].trim(); String key = decodedAuth.split(":")[1].trim(); if (!username.equals("") && !key.equals("") && UserData.getUserByUsername(username) != null) { User user = UserData.getUserByUsername(username); if(user != null){ if (UserData.validateUserKey(user, key)) { mUser = user; authenticated = true; } } } } } } } // Default Unauthorized if we are not authenticated if (!authenticated && secure) { if (!handleUnauthorized(req)) { req.response().putHeader(HttpHeaders.Names.WWW_AUTHENTICATE, "Basic realm=\"username and api key required\""); errorResponse(req, "Unauthorized", "You are unauthorized to make this request", 401); return; } } final User finalUser = mUser; /** * End Authorization */ try { handleAuthorized(req, finalUser); } catch (Exception e){ errorResponse(req, "API Error", e.getMessage(), 500); } } public abstract void handleAuthorized(HttpServerRequest request, User user); public abstract boolean handleUnauthorized(HttpServerRequest request); }